/*
 * Ant Colony Optimization
 * Alex Oliveira
 * Heitor Luiz
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "comum.h"
#include "simulacao.h"
#include "vrml.h"

/* Quantidade mínima de parâmetros que o programa recebe. */
#define QUANT_PARAM 5

static void recebe_parametros(int argc, char **argv);
static void roda_simulacao();

static int qtdformigas, num_terreno;
static Formiga formigas[MAX_FORMIGAS];

int main(int argc, char **argv) {

	/* Valida os parâmetros do programa. */
	recebe_parametros(argc, argv);

	/* Inicializa o terreno. */
	init_terreno(num_terreno);

	/* Cria as formigas. */
	for (int i = 0; i < qtdformigas; i++) {
		formigas[i] = new_formiga();
	}

	/* Roda a simulação. */
	roda_simulacao();

	/* Encerra o programa. */
	for (int i = 0; i < qtdformigas; i++) {
		del_formiga(&formigas[i]);
	}
	junta_arquivos();
	end_terreno();
	return 0;
}


/*
 * Valida os parâmetros de entrada do programa, faz o parsing deles e guardas
 * nas variáveis globais.
 */
void recebe_parametros(int argc, char **argv) {


	/* Checa a quantidade de parâmetros. */
	if (argc < QUANT_PARAM) {
		puts("ACO - Ant Colony Optimization\n\n"
			"Use o programa da seguinte forma:\n"
				"\t aco <qtdformigas> <turnos> <qtdferormonio> <evaporacao> <arqterreno>\n"
			"onde:\n"
				"\t <qtdformigas> é o número de formigas\n"
				"\t <turnos> é a quantidade de turnos da simulação\n"
				"\t <qtdferormonio> é quanto ferormônio a formiga coloca\n"
				"\t <evaporacao> é a taxa de evaporação do ferormônio\n"
				"\t <arqterreno> é o número do arquivo de terreno");
		exit(EXIT_FAILURE);
	}

	/* Parsing das variáveis. */
	qtdformigas = abs(atoi(argv[1]));
	if (qtdformigas > MAX_FORMIGAS) {
		puts("qtdformigas deve ser no máximo MAX_FORMIGAS");
		exit(EXIT_FAILURE);
	}
	turnos = abs(atoi(argv[2]));
	if (turnos > MAX_TURNOS) {
		puts("turnos deve ser no máximo MAX_TURNOS");
		exit(EXIT_FAILURE);
	}
	qtdferormonio = fabs(atof(argv[3]));
	if (qtdferormonio > MAX_FERORMONIO) {
		puts("qtdferormonio deve ser no máximo MAX_FERORMONIO");
		exit(EXIT_FAILURE);
	}
	evaporacao = abs(atoi(argv[4]));
	if (evaporacao > MAX_EVAPORACAO) {
		puts("evaporacao deve ser no máximo MAX_EVAPORACAO");
		exit(EXIT_FAILURE);
	}
	num_terreno = abs(atoi(argv[5]));
	if (num_terreno < 1 || num_terreno > 5) {
		puts("arqterreno deve ser um número de 1 a 5");
		exit(EXIT_FAILURE);
	}
}


/*
 * Executa todos os turnos da simulação.
 * Coloca todas as formigas para andar ao mesmo tempo.
 * Cada turno tem tamanho suficiente para uma formiga ir e voltar até a
 * distância máxima que ela consegue.
 */
void roda_simulacao() {
	for (int i = 0; i < turnos; i++) {
		for (int j = 0; j < MAX_CAMINHO * 2; j++) {
			for (int k = 0; k < qtdformigas; k++) {
				prox_passo(&formigas[k]);
			}
			evapora();
		}
	}
}
